// forked from dizgid's forked from: [朝ワン]何か涼しそうなやつ > 麦
// forked from bkzen's [朝ワン]何か涼しそうなやつ
// forked from hacker_ij48yrxl's flash on 2009-5-10
package 
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Graphics;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.filters.BlurFilter;
	import flash.geom.ColorTransform;
	import flash.geom.Point;
	
	import net.hires.debug.Stats;
	
	[SWF(width="465", height="465", backgroundColor="0x000000", frameRate="24")]
	public class SnowFall extends Sprite 
	{
		
		public static const PERLIN_WIDTH:int = 40;
		public static const PERLIN_HEIGHT:int = 60;
		public static const WIDTH:int = 500;
		public static const HEIGHT:int = 400;
		public static const num:Number = 255;
		
		private var px:Number = 0;
		private var offset:Array;
		private var sh:Shape;
		private var bmd:BitmapData;
		private var p:Point;
		private var blur:BlurFilter;
		private var colorTf:ColorTransform;
		private var bmpData:BitmapData;
		
		private var _randPos:Array;
		
		public function SnowFall():void 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			
			stage.quality = "low";
			// entry point
			//filters = [new BlurFilter(4,0)];
			offset = [new Point(px += 0.5, 0), new Point( -px / 2, 0), new Point(0, 0)];
			bmpData = new BitmapData(PERLIN_WIDTH, PERLIN_HEIGHT);
			
			sh = new Shape();
			bmd = new BitmapData(465, 465, false, 0x0);
			p = new Point();
			blur = new BlurFilter(8, 8);
			colorTf = new ColorTransform(1, 1, 1, 1, -1, -10, -20, -5);
			createRandPos();
			
			addChild(new Bitmap(bmd, "auto", true));
			addChild(new Stats());
			
			addEventListener(Event.ENTER_FRAME, loop);
		}
		private function createRandPos():void
		{
			_randPos = [];
			for(var i:int=0; i < PERLIN_WIDTH * PERLIN_HEIGHT; i++){
				_randPos.push(Math.random()*20);
			}
		}
		
		private function loop(e:Event):void {
			Point(offset[0]).x = px += 0.8;
			Point(offset[1]).x = -px / 2;
			bmpData.perlinNoise(PERLIN_WIDTH, PERLIN_HEIGHT, 3, 6456, true, true, 3, false, offset);
			var g: Graphics = sh.graphics;
			g.clear();
			g.lineStyle(0, 0xFFFFFF, 0.1);
			
			var j:int = 1;
			var value1:int;
			var value2:int;
			var i:int = 1;
			
			var vect:Vector.<uint> = bmpData.getVector(bmpData.rect);
			
			for (; j < PERLIN_HEIGHT - 1; j++) { 
				value1 = bmpData.getPixel(0, j);
				value1 = value1 >> 16;
				value2 = bmpData.getPixel(1, j);
				value2 = value2 >> 16;
				g.moveTo(0 * WIDTH / (PERLIN_WIDTH -1), value1 + (HEIGHT >> 1) - 128 + j * 3);
				for (i = 1; i < PERLIN_WIDTH - 1; i++) {
					
					value1 = bmpData.getPixel(i, j);
					value1 = value1 >> 16;
					value2 = bmpData.getPixel(i + 1, j);
					value2 = value2 >> 16;
					g.moveTo(i * WIDTH / (PERLIN_WIDTH - 1) + _randPos[i*j] -30, HEIGHT / 2 + j * 5 + 20);
					g.curveTo( value1 + i * WIDTH / (PERLIN_WIDTH - 1) -128 + _randPos[i*j] -30,  HEIGHT / 2 + j * 4.5 - _randPos[i*j],
						value1 + i * WIDTH / (PERLIN_WIDTH - 1) -128 + _randPos[i*j] -30,  HEIGHT / 2 + j * 4.0 - _randPos[i*j]  );
				}
			}
			bmd.lock();
			bmd.colorTransform(bmd.rect, colorTf);
			bmd.applyFilter(bmd, bmd.rect, p, blur);
			bmd.draw(sh);
			bmd.unlock();
		}
		
	}
	
}